﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class BaseEnemy : MonoBehaviour , Hittable
{

	public SpawenerScript mySpawner;



	protected Vector3 startPos;
	protected Vector3 moveToPos;
	protected Vector2 playAreaLimits = new Vector3(20.0f,20.0f);
	float ShootTimer = 0.0f;
	float shootTimerMax = 1.0f;

	public float rotateSpeed = 10.0f;
	public float moveSpeed = 3.0f;

	public float health = 10.0f;
	protected int maxNumOfCoins = 10;
	protected int minNumOfCoins = 1;

	protected Transform player;
	protected float minAttackDistance = 5.0f;
	protected bool canShoot = true;

	protected Pooler poolManager;
	protected Stack<GameObject> myBulletPool;

	// Use this for initialization
	protected virtual void Start ()
	{
		SetUp ();
		player = GameObject.FindGameObjectWithTag ("Player").transform;
		poolManager = GameObject.FindGameObjectWithTag ("Pooler").GetComponent<Pooler>();
		myBulletPool = poolManager.basicBulletPool;
		startPos = new Vector3 (transform.position.x, 1.0f, transform.position.z);
		moveToPos = startPos;
	}

	protected virtual void SetUp()
	{

	}

	Camera mainCam = Camera.main;
	Vector2 offScreenIndicatorScreenPos = new Vector2 (10.0f, 10.0f);
	// Update is called once per frame
	void Update ()
	{



		transform.Translate (Vector3.forward * moveSpeed * Time.deltaTime);

		if(PlayerInRange())
		{
			Attack();
			if(!canShoot)
				ShootClock();
		}
		else
		{
			Patrol();
		}

		PersonalUpdate ();
			
	}

	void ShootClock()
	{
		ShootTimer += Time.deltaTime;
		if(ShootTimer >= shootTimerMax)
		{
			ShootTimer = 0.0f;
			canShoot = true;
		}
			
	}

	public void Hit(float damage)
	{
		WasHit (damage);
	}

	public virtual void WasHit(float damage)
	{
		health -= damage;
		if(health < 0)
			Die();
	}


	public float explosionPointRadius = 0.5f;
	public float explosionRadius = 10.0f;
	public float explosionForce = 300.0f;
	public void Die()
	{
		for(int i = 0; i< 40; i++)
		{
			GameObject Gib = poolManager.GetFromPool(poolManager.DeathGibPool);
			if(Gib != null)
			{
				Gib.transform.position = transform.position  + Random.insideUnitSphere;
				Gib.rigidbody.AddExplosionForce (explosionForce, transform.position, explosionRadius);
			}
			else break;
		}

		for(int i = 0; i< Random.Range(1,10); i++)
		{
			GameObject coin = poolManager.GetFromPool(poolManager.coinPool);
			if(coin != null)
			{
				coin.transform.position = transform.position + Random.insideUnitSphere+ Vector3.up;
				Vector3 randomPos = transform.position + Random.insideUnitSphere;
				coin.transform.rotation = Quaternion.LookRotation(randomPos);
			}
			else break;
		}

		int decider = Random.Range (0, 10);
		if(decider > 6)
		{
			decider = decider % 3;
			GameObject pickup = null;
			if(decider == 0) pickup = poolManager.GetFromPool(poolManager.healthPool);
			if(decider == 1) pickup = poolManager.GetFromPool(poolManager.sheildPool);
			if(decider == 2) pickup = poolManager.GetFromPool(poolManager.ammoPool);

			if(pickup != null)
			{
				pickup.transform.position = transform.position + Random.insideUnitSphere+ Vector3.up;
				Vector3 randomPos = transform.position + Random.insideUnitSphere;
				pickup.transform.rotation = Quaternion.LookRotation(randomPos);
			}

		}
		mySpawner.EnemyDied ();
		Destroy (gameObject);
	}

	protected virtual void Attack()
	{
	}

	protected virtual void Patrol()
	{
		float dist = Vector3.Distance (transform.position, moveToPos);
		if(dist > 0.10f)
		{
			Vector3 dir = moveToPos - transform.position;
			transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(dir), rotateSpeed * Time.deltaTime);
		}
		else
		{
			moveToPos = new Vector3(Random.Range(-playAreaLimits.x, playAreaLimits.x), 1, Random.Range(-playAreaLimits.y, playAreaLimits.y));
		}
	}

	protected virtual void PersonalUpdate ()
	{
	}

	bool PlayerInRange()
	{
		bool isInRange = false;
		if(Vector3.Distance(transform.position, player.position) < minAttackDistance)
			isInRange = true;
		return isInRange;
	}

	void OnGUI()
	{
		float boxSize = 50.0f;
		Rect offScreenRect = new Rect (offScreenIndicatorScreenPos.x - 0.5f * boxSize, offScreenIndicatorScreenPos.y- 0.5f * boxSize, boxSize, boxSize);
		GUI.Box (offScreenRect, "OffScreen!!");
	}
}
